package dipl.algorithm.math.fp.primitive;

/**
 *
 */
public class Interval1df {

	//
	// CONSTRUCTOR METHODS
	//

	public Interval1df() {
		l = 0.0;
		u = 0.0;
	}

	public Interval1df( double a, double b ) {
		l = a <= b ? a : b;
		u = a > b ? a : b;
	}

  public Interval1df( Interval1df o ) {
		this.l = o.l;
		this.u = o.u;
  }

	//
	// PROPERTIES
	//

	/**
	 * 
	 */
	public static Interval1df EmptyInterval() {
		return new Interval1df( 0.0, 0.0 );
	}

  /**
	 *  lower interval border
	 */
	public double L() {
		return l;
	}

	/**
	 * interval length
	 */
	public double Length() {
		return u-l;
	}

	/**
	 * upper interval border
	 */
	public double U() {
		return u;
	}

	/**
	 * unit interval [0.0,1.0]
	 */
	public static Interval1df UnitInterval() {
		return new Interval1df( 0.0, 1.0 );
	}

	//
  // PUBLIC METHODS
	//

	/**
	 * Tests whether or not given value x is contained in interval
	 * @param x
	 * @return contained or not
	 */
	public boolean ContainsValue( double x ) {
		return (l <= x && x <= u);
	}

	@Override
	@SuppressWarnings("EqualsWhichDoesntCheckParameterClass")
	public boolean equals( Object obj ) {
		Interval1df o = (Interval1df)obj;
		return (o.l == this.l && o.u == this.u);
	}

	@Override
	public int hashCode() {
		return super.hashCode();
	}

	/**
	 * Tests whether or not interval intersects with given one.
	 * @param other
	 * @return
	 */
	public boolean Intersects( Interval1df other ) {
		return u >= other.l && l <= other.u;
	}

	/**
	 * Tests whether or not interval properly intersects with given one.
	 * @param other
	 * @return
	 */
	public boolean ProperlyIntersects( Interval1df other ) {
		return u > other.l && l < other.u;
	}

	/**
	 * Tests whether interval lies left of given point a
	 * @param a
	 * @return
	 */
	public boolean LeftOf( double a ) {
		return (u < a);
	}

	/**
	 * Tests whether interval lies right of given point a
	 * @param a
	 * @return
	 */
	public boolean RightOf( double a ) {
		return (l > a);
	}

	/**
	 * Sets bounds of interval. Use method if it is known that l < u
	 * @param l
	 * @param u
	 */
	public void SetBoundsUnsafe( double l, double u ) {
		this.l = l;
		this.u = u;
	}

	/**
	 * Sets bounds of interval. It is checked which value is smaller.
	 * @param a
	 * @param b
	 */
	public void SetBoundsSafe( double a, double b ) {
		l = a <= b ? a : b;
		u = a > b ? a : b;
	}

	/**
	 * Sets lower bound of interval. Use method if it is known that given l < this.u
	 * @param l
	 */
	public void SetLUnsafe( double l ) {
		this.l = l;
	}

	/**
	 * Sets upper bound of interval. Use method if it is known that given this.l < u
	 * @param u
	 */
	public void SetUUnsafe( double u ) {
		this.u = u;
	}

	@Override
	public String toString() {
		return "["+l+", "+u+"]";
	}

	//
	// MEMBERS
	//

	/** l interval border */
	private double l;
	/** u interval border */
	private double u;
}

